import os
import wx
import cv2
from core.adb_interface import AdbInterface
from core.yaml_extra import YamlLoaderWithLog, YamlDumperWithLog
from widgets.picture_dialog import DlgPictureWithAction, DlgActionsSimulator
from logic.custom_logic import CustomScriptThread


class DlgCustomScript(wx.Dialog):
    def __init__(self, parent, dir, file=None, dev_sn=None):
        wx.Dialog.__init__(self, parent=parent, title="添加脚本", style=wx.DEFAULT_FRAME_STYLE)
        # data
        self.file_dir = dir
        self.script_file = file
        self.device_sn = dev_sn
        self.adb = AdbInterface()
        self.adb.set_device(dev_sn) if dev_sn is not None else False
        self.adb_enabled = dev_sn is not None
        self.script = {"name": "", "tip": "", "times": 1, "actions": []}
        self.act_all = ["click", "press", "slide", "key", "cap", "call", "text", "msg", "nop"]
        self.act_name_all = ["点击", "按住", "滑动", "按键", "截屏", "调用", "输入", "消息", "等待"]
        # controls
        self.lbl_name = wx.StaticText(self, label="脚本名称：")
        self.txt_name = wx.TextCtrl(self)
        self.lbl_file = wx.StaticText(self, label="脚本文件：")
        self.txt_file = wx.TextCtrl(self)
        self.lbl_tip = wx.StaticText(self, label="文字提示：")
        self.txt_tip = wx.TextCtrl(self)
        self.lbl_times = wx.StaticText(self, label="执行次数(无限:-1)：")
        self.num_times = wx.SpinCtrl(self, min=-1, max=10000, initial=1)

        self.lbl_actions = wx.StaticText(self, label="操作命令：")
        self.lbl_act = wx.StaticText(self, label="指令：")
        self.cmb_act = wx.ComboBox(self, choices=self.act_name_all, style=wx.CB_READONLY | wx.TEXT_ALIGNMENT_CENTER)
        self.lbl_x = wx.StaticText(self, label="x：")
        self.num_x = wx.SpinCtrl(self, min=0, max=100000, style=wx.TE_PROCESS_ENTER)
        self.lbl_y = wx.StaticText(self, label="y：")
        self.num_y = wx.SpinCtrl(self, min=0, max=100000, style=wx.TE_PROCESS_ENTER)
        self.lbl_x2 = wx.StaticText(self, label="x2：")
        self.num_x2 = wx.SpinCtrl(self, min=0, max=100000, style=wx.TE_PROCESS_ENTER)
        self.lbl_y2 = wx.StaticText(self, label="y2：")
        self.num_y2 = wx.SpinCtrl(self, min=0, max=100000, style=wx.TE_PROCESS_ENTER)
        self.lbl_key = wx.StaticText(self, label="键：")
        self.cmb_key = wx.ComboBox(self, style=wx.TE_PROCESS_ENTER | wx.CB_READONLY,
                                   choices=list(AdbInterface.KeyCode.__members__.keys()))
        self.lbl_cap_name = wx.StaticText(self, label="标识名：")
        self.lbl_call_file = wx.StaticText(self, label="文件：")
        self.btn_call_file = wx.Button(self, label="浏览...")
        self.lbl_text = wx.StaticText(self, label="文本：")
        self.txt_text = wx.TextCtrl(self, style=wx.TE_PROCESS_ENTER)
        self.lbl_time = wx.StaticText(self, label="时间(s)：")
        self.num_time = wx.SpinCtrlDouble(self, min=0., max=100000000., inc=0.5, style=wx.TE_PROCESS_ENTER)
        self.btn_action_add = wx.Button(self, label="添加")
        self.btn_action_mod = wx.Button(self, label="修改")
        self.btn_action_test = wx.Button(self, label="测试")
        self.btn_action_simulate = wx.Button(self, label="模拟")
        self.lst_actions = wx.ListBox(self)
        self.btn_actions_up = wx.Button(self, label="↑", size=(25, 25))
        self.btn_actions_down = wx.Button(self, label="↓", size=(25, 25))
        self.btn_actions_del = wx.Button(self, label="X", size=(25, 25))
        self.btn_actions_deselect = wx.Button(self, label="□", size=(25, 25))
        self.btn_actions_record = wx.Button(self, label="●", size=(25, 25))
        self.btn_save = wx.Button(self, label="保存")
        self.btn_ok = wx.Button(self, id=wx.ID_OK, label="保存并关闭")
        self.btn_cancel = wx.Button(self, id=wx.ID_CANCEL, label="关闭")
        # layout
        self.box_all = wx.BoxSizer(wx.VERTICAL)
        self.box_name = wx.BoxSizer()
        self.box_name.AddMany([(self.lbl_name, 0, wx.ALIGN_CENTER_VERTICAL | wx.LEFT, 10),
                               (self.txt_name, 2, wx.ALIGN_CENTER_VERTICAL | wx.RIGHT, 5),
                               (self.lbl_file, 0, wx.ALIGN_CENTER_VERTICAL | wx.LEFT, 5),
                               (self.txt_file, 2, wx.ALIGN_CENTER_VERTICAL | wx.RIGHT, 5),
                               (self.lbl_times, 0, wx.ALIGN_CENTER_VERTICAL | wx.LEFT, 5),
                               (self.num_times, 1, wx.ALIGN_CENTER_VERTICAL | wx.RIGHT, 5)
                               ])
        self.box_tip = wx.BoxSizer()
        self.box_tip.AddMany([(self.lbl_tip, 0, wx.LEFT, 10),
                              (self.txt_tip, 1, wx.EXPAND | wx.RIGHT, 10)])
        self.box_action = wx.BoxSizer()
        self.num_x.SetMinSize((20, 25))
        self.num_y.SetMinSize((20, 25))
        self.num_x2.SetMinSize((20, 25))
        self.num_y2.SetMinSize((20, 25))
        self.cmb_key.SetMinSize((20, 25))
        self.txt_text.SetMinSize((20, 25))
        self.num_time.SetMinSize((20, 25))
        self.btn_call_file.SetMinSize((50, 25))
        self.box_action.AddMany([(self.lbl_act, 0, wx.ALIGN_CENTER_VERTICAL | wx.LEFT, 5),
                                 (self.cmb_act, 1, wx.ALIGN_CENTER_VERTICAL),
                                 (self.lbl_x, 0, wx.ALIGN_CENTER_VERTICAL | wx.LEFT, 5),
                                 (self.num_x, 3, wx.ALIGN_CENTER_VERTICAL),
                                 (self.lbl_y, 0, wx.ALIGN_CENTER_VERTICAL | wx.LEFT, 5),
                                 (self.num_y, 3, wx.ALIGN_CENTER_VERTICAL),
                                 (self.lbl_x2, 0, wx.ALIGN_CENTER_VERTICAL | wx.LEFT, 5),
                                 (self.num_x2, 3, wx.ALIGN_CENTER_VERTICAL),
                                 (self.lbl_y2, 0, wx.ALIGN_CENTER_VERTICAL | wx.LEFT, 5),
                                 (self.num_y2, 3, wx.ALIGN_CENTER_VERTICAL),
                                 (self.lbl_key, 0, wx.ALIGN_CENTER_VERTICAL | wx.LEFT, 5),
                                 (self.cmb_key, 3, wx.ALIGN_CENTER_VERTICAL),
                                 (self.lbl_cap_name, 0, wx.ALIGN_CENTER_VERTICAL | wx.LEFT, 5),
                                 (self.lbl_call_file, 0, wx.ALIGN_CENTER_VERTICAL | wx.LEFT, 5),
                                 (self.lbl_text, 0, wx.ALIGN_CENTER_VERTICAL | wx.LEFT, 5),
                                 (self.txt_text, 3, wx.ALIGN_CENTER_VERTICAL),
                                 (self.btn_call_file, 0, wx.ALIGN_CENTER_VERTICAL | wx.LEFT, 3),
                                 (self.lbl_time, 0, wx.ALIGN_CENTER_VERTICAL | wx.LEFT, 5),
                                 (self.num_time, 4, wx.ALIGN_CENTER_VERTICAL)])
        self.box_action_op = wx.BoxSizer()
        self.btn_action_add.SetMinSize((40, 25))
        self.btn_action_mod.SetMinSize((40, 25))
        self.btn_action_test.SetMinSize((40, 25))
        self.btn_action_simulate.SetMinSize((40, 25))
        self.box_action_op.AddMany([(self.box_action, 1, wx.EXPAND | wx.ALIGN_CENTER_VERTICAL | wx.LEFT, 5),
                                    (self.btn_action_add, 0, wx.ALIGN_CENTER_VERTICAL | wx.LEFT | wx.RIGHT, 5),
                                    (self.btn_action_mod, 0, wx.ALIGN_CENTER_VERTICAL | wx.RIGHT, 5),
                                    (self.btn_action_test, 0, wx.ALIGN_CENTER_VERTICAL | wx.RIGHT, 5),
                                    (self.btn_action_simulate, 0, wx.ALIGN_CENTER_VERTICAL | wx.RIGHT, 10)])
        self.box_actions_op = wx.BoxSizer(wx.VERTICAL)
        self.box_actions_op.AddMany([(self.btn_actions_up, 0, wx.TOP, 5),
                                     (self.btn_actions_down, 0, wx.TOP, 5),
                                     (self.btn_actions_del, 0, wx.TOP, 5),
                                     (self.btn_actions_deselect, 0, wx.TOP, 5),
                                     (self.btn_actions_record, 0, wx.TOP, 5)])
        self.box_actions = wx.BoxSizer()
        self.box_actions.AddMany([(self.lst_actions, 1, wx.EXPAND | wx.LEFT, 5),
                                  (self.box_actions_op, 0, wx.LEFT | wx.RIGHT, 5)])
        self.box_button = wx.BoxSizer()
        self.box_button.AddMany([(self.btn_save, 1, wx.ALIGN_CENTER_VERTICAL | wx.LEFT, 10),
                                 (self.btn_ok, 1, wx.ALIGN_CENTER_VERTICAL | wx.LEFT, 10),
                                 (self.btn_cancel, 1, wx.ALIGN_CENTER_VERTICAL | wx.LEFT | wx.RIGHT, 10)])
        self.box_all.AddMany([(self.box_name, 0, wx.EXPAND | wx.TOP, 5),
                              (self.box_tip, 0, wx.EXPAND | wx.TOP, 5),
                              (self.lbl_actions, 0, wx.TOP | wx.LEFT, 10),
                              (self.box_action_op, 0, wx.EXPAND | wx.TOP, 5),
                              (self.box_actions, 1, wx.EXPAND | wx.TOP, 5),
                              (self.box_button, 0, wx.EXPAND | wx.TOP | wx.BOTTOM, 5)])
        self.SetSize(800, 500)
        self.SetSizer(self.box_all)
        # event
        self.SetDefaultItem(self.btn_ok)
        self.cmb_act.Bind(wx.EVT_COMBOBOX, self.change_act)
        self.btn_call_file.Bind(wx.EVT_BUTTON, self.select_call_file)
        self.lst_actions.Bind(wx.EVT_LISTBOX_DCLICK, self.edit_action)
        self.btn_action_add.Bind(wx.EVT_BUTTON, self.add_action)
        self.btn_action_mod.Bind(wx.EVT_BUTTON, self.mod_action)
        self.btn_action_test.Enable(self.adb_enabled)
        self.btn_action_test.Bind(wx.EVT_BUTTON, self.test_action)
        self.btn_action_simulate.Enable(self.adb_enabled)
        self.btn_action_simulate.Bind(wx.EVT_BUTTON, self.input_action_from_screen)
        self.btn_actions_up.Bind(wx.EVT_BUTTON, self.up_action)
        self.btn_actions_down.Bind(wx.EVT_BUTTON, self.down_action)
        self.btn_actions_del.Bind(wx.EVT_BUTTON, self.del_action)
        self.btn_actions_deselect.Bind(wx.EVT_BUTTON, self.desel_action)
        self.btn_actions_record.Bind(wx.EVT_BUTTON, self.record_actions)
        self.btn_save.Bind(wx.EVT_BUTTON, self.on_save)
        self.btn_ok.Bind(wx.EVT_BUTTON, self.on_ok)
        # self.btn_cancel.Bind(wx.EVT_BUTTON, self.on_cancel)
        # ["click", "press", "slide", "key", "cap", "call", "text", "msg", "nop"]
        self.act_ctrl_all = [self.lbl_x, self.num_x, self.lbl_y, self.num_y,
                             self.lbl_x2, self.num_x2, self.lbl_y2, self.num_y2,
                             self.lbl_key, self.cmb_key,
                             self.lbl_cap_name, self.lbl_text, self.txt_text,
                             self.lbl_call_file, self.btn_call_file,
                             self.lbl_time, self.num_time]
        self.act_show_ctrl = [[self.lbl_x, self.num_x, self.lbl_y, self.num_y],  # click
                              [self.lbl_x, self.num_x, self.lbl_y, self.num_y, self.lbl_time, self.num_time],  # press
                              [self.lbl_x, self.num_x, self.lbl_y, self.num_y,  # slide
                               self.lbl_x2, self.num_x2, self.lbl_y2, self.num_y2, self.lbl_time, self.num_time],
                              [self.lbl_key, self.cmb_key],  # key
                              [self.lbl_cap_name, self.txt_text],  # cap
                              [self.lbl_call_file, self.txt_text, self.btn_call_file],  # call
                              [self.lbl_text, self.txt_text],  # text
                              [self.lbl_text, self.txt_text],  # msg
                              [self.lbl_time, self.num_time]]  # nop
        self.act_ctrl_val = [{"x": ("位置: (", self.num_x), "y": (", ", self.num_y), "_": (")", None)},
                             {"x": ("位置: (", self.num_x), "y": (", ", self.num_y), "time": ("), 时间: ", self.num_time)},
                             {"x1": ("路径: (", self.num_x), "y1": (", ", self.num_y), "x2": (") => (", self.num_x2),
                              "y2": (", ", self.num_y2), "time": ("), 时间: ", self.num_time)},
                             {"name": ("键名: ", self.cmb_key)},
                             {"name": ("标识名: ", self.txt_text)},
                             {"file": ("文件: ", self.txt_text)},
                             {"value": ("文本: ", self.txt_text)},
                             {"value": ("内容: ", self.txt_text)},
                             {"time": ("时间: ", self.num_time)}]
        assert len(self.act_all) == len(self.act_name_all)
        assert len(self.act_all) == len(self.act_ctrl_val) == len(self.act_show_ctrl)
        self.init_data()

    def init_data(self):
        if self.script_file is not None:
            self.txt_file.Disable()
            if not self.load_data():
                wx.MessageBox("输入文件不存在！", "编辑脚本")
            self.txt_name.SetValue(self.script["name"] if "name" in self.script else "")
            self.txt_file.SetValue(self.script_file)
            self.txt_tip.SetValue(self.script["tip"] if "tip" in self.script else "")
            self.num_times.SetValue(self.script["times"] if "times" in self.script else (
                                    -1 if "loop" in self.script else 1))
            self.cvt_list_to_actions(self.script["actions"] if "actions" in self.script else [])
        self.cmb_act.Select(0)
        self.change_act(0)

    def load_data(self):
        if "name" in self.script and self.script["name"] is not None:
            self.txt_name.SetValue(self.script["name"])
        if self.script_file is None:
            return False
        self.txt_file.SetValue(self.script_file)
        file_name = os.path.join(self.file_dir, self.script_file)
        if not os.path.exists(file_name):
            return False
        try:
            self.script = YamlLoaderWithLog(file_name, raise_again=True).load_dict()
        except Exception as ex:
            wx.MessageBox(str(ex), "加载脚本数据")
        return True

    def save_data(self):
        if self.script_file is None:
            return False
        if not self.script_file.endswith(".yml"):
            self.script_file += ".yml"
        file_name = os.path.join(self.file_dir, self.script_file)
        try:
            YamlDumperWithLog(file_name, raise_again=True)\
                .dump(self.script,
                      default_flow_style=False,
                      encoding="utf-8",
                      allow_unicode=True,
                      sort_keys=False)
        except Exception as ex:
            wx.MessageBox(str(ex), "存储脚本数据")
        return True

    def cvt_list_to_actions(self, actions):
        for act in actions:
            act_idx = self.act_all.index(act["act"]) if "act" in act and self.act_all.count(act["act"]) > 0 else -1
            if act_idx < 0:
                action_str = str(act)
            else:
                action_str = self.act_name_all[act_idx] + " ( "
                for k, v in self.act_ctrl_val[act_idx].items():
                    if k == "_" or k not in act:
                        action_str += v[0]
                    else:
                        action_str += v[0] + str(act[k])
                action_str += " )"
            self.lst_actions.Append(action_str, act)
        pass

    def cvt_action_to_control(self, lst_sel):
        data = self.lst_actions.GetClientData(lst_sel)
        if data is None:
            return False
        act_idx = self.act_all.index(data["act"]) \
            if "act" in data and self.act_all.count(data["act"]) > 0 else -1
        if act_idx < 0:
            return False
        self.cmb_act.Select(act_idx)
        self.change_act(act_idx)
        if data["act"] == "key":
            if "name" in data:
                self.cmb_key.SetValue(data["name"])
            elif "value" in data:
                self.cmb_key.SetValue(AdbInterface.KeyCode(int(data["value"])).name)
        else:
            for k, v in self.act_ctrl_val[act_idx].items():
                if k == "_":
                    pass
                else:
                    v[1].SetValue(data[k])
        return True

    def cvt_control_to_action(self):
        """
        convert control value to action information
        :return: (dict, act)
        """
        act_sel = self.cmb_act.GetSelection()
        if act_sel is wx.NOT_FOUND:
            return {}, None
        act = self.act_all[act_sel]
        act_name = self.act_name_all[act_sel]
        action = {"act": act}
        action_str = act_name + " ( "
        if act == "key":
            if self.cmb_key.GetSelection() is wx.NOT_FOUND:
                return None, None
            key_name = self.cmb_key.GetValue()
            action["name"] = key_name
            action_str += "键名: " + key_name
            key_value = AdbInterface.KeyCode.NONE
            for k in AdbInterface.KeyCode.__members__.items():
                if k[0] == key_name:
                    key_value = k[1]
                    break
            if key_value is not AdbInterface.KeyCode.NONE:
                action["value"] = key_value.value
                action_str += ", 键值: " + str(key_value.value)
        else:
            for k, v in self.act_ctrl_val[act_sel].items():
                if k == "_":
                    pass
                else:
                    action[k] = v[1].GetValue()
                    if action[k] is None or (isinstance(action[k], str) and len(action[k]) is 0):
                        return None, None
                if v[1] is None:
                    action_str += v[0]
                else:
                    action_str += v[0] + str(v[1].GetValue())
        action_str += " )"
        return action, action_str

    def cvt_points_to_action(self, points: [list, tuple]):
        # convert yaml
        if points[0] is None:
            act_idx = self.act_all.index("nop")
            if act_idx < 0:
                return {}, None
            action = {"act": "nop", "time": points[2]}
        elif points[1] is None:
            if points[2] < 0.5:
                act_idx = self.act_all.index("click")
                if act_idx < 0:
                    return {}, ""
                action = {"act": "click", "x": points[0][0], "y": points[0][1]}
            else:
                act_idx = self.act_all.index("press")
                if act_idx < 0:
                    return {}, None
                action = {"act": "press", "x": points[0][0], "y": points[0][1], "time": points[2]}
        else:
            act_idx = self.act_all.index("slide")
            if act_idx < 0:
                return {}, None
            action = {"act": "slide", "x1": points[0][0], "y1": points[0][1],
                      "x2": points[1][0], "y2": points[1][1], "time": points[2]}
        # convert list text
        action_str = self.act_name_all[act_idx] + " ( "
        for k, v in self.act_ctrl_val[act_idx].items():
            if v[1] is None:
                action_str += v[0]
            else:
                action_str += v[0] + str(action[k])
        action_str += " )"
        return action, action_str

    def change_act(self, e: [int, wx.CommandEvent] = -1):
        if isinstance(e, int):
            act_sel = e
        else:
            act_sel = e.GetSelection()
        # ["click", "press", "slide", "key", "text", "nop"]
        num = self.box_action.GetItemCount()
        ctrl_show = self.act_show_ctrl[act_sel]
        for ctrl in self.act_ctrl_all:
            if ctrl in ctrl_show:
                ctrl.Show()
            else:
                ctrl.Hide()
        self.Layout()
        pass

    def select_call_file(self, e):
        fd = wx.FileDialog(self, message="选择脚本文件", defaultDir=self.file_dir,
                           wildcard="脚本文件|*.yml", style=wx.FD_FILE_MUST_EXIST | wx.FD_OPEN)
        fd.SetPath(self.file_dir + "/")
        if fd.ShowModal() == wx.ID_OK:
            p1 = os.path.abspath(self.file_dir)
            p2 = os.path.abspath(os.path.dirname(fd.GetPath()))
            if p1 not in p2:
                wx.MessageBox("不允许切换到上级目录，只可以选择本设备下的脚本！", "脚本目录错误", parent=self)
            else:
                rel_p = os.path.relpath(fd.GetPath(), self.file_dir)
                self.txt_text.SetValue(rel_p)
        pass

    def edit_action(self, e: [int, wx.CommandEvent] = -1):
        if isinstance(e, int):
            sel = e
        else:
            sel = e.GetSelection()
        return self.cvt_action_to_control(sel)

    def add_action(self, e=None):
        action_sel = self.lst_actions.GetSelection()
        act, str = self.cvt_control_to_action()
        if str is None:
            return
        if action_sel is wx.NOT_FOUND:
            self.lst_actions.ScrollLines(self.lst_actions.GetCount())
            self.lst_actions.Append(str, act)
            self.lst_actions.ScrollLines(self.lst_actions.GetCount())
        else:
            self.lst_actions.Insert(str, action_sel + 1, act)
            self.lst_actions.Select(action_sel + 1)
        pass

    def del_action(self, e=None):
        action_sel = self.lst_actions.GetSelection()
        if action_sel is wx.NOT_FOUND:
            return
        self.lst_actions.Delete(action_sel)
        pass

    def mod_action(self, e=None):
        action_sel = self.lst_actions.GetSelection()
        if action_sel is wx.NOT_FOUND:
            return
        act, str = self.cvt_control_to_action()
        if str is None:
            return
        self.lst_actions.Delete(action_sel)
        self.lst_actions.Insert(str, action_sel, act)
        pass

    def up_action(self, e=None):
        sel = self.lst_actions.GetSelection()
        if sel is wx.NOT_FOUND:
            return
        if sel < 1:
            return
        label = self.lst_actions.GetString(sel)
        data = self.lst_actions.GetClientData(sel)
        self.lst_actions.Delete(sel)
        self.lst_actions.Insert(label, sel - 1, data)
        self.lst_actions.Select(sel - 1)
        pass

    def down_action(self, e=None):
        sel = self.lst_actions.GetSelection()
        if sel is wx.NOT_FOUND:
            return
        if sel > self.lst_actions.GetCount() - 2:
            return
        label = self.lst_actions.GetString(sel)
        data = self.lst_actions.GetClientData(sel)
        self.lst_actions.Delete(sel)
        self.lst_actions.Insert(label, sel + 1, data)
        self.lst_actions.Select(sel + 1)
        pass

    def desel_action(self, e=None):
        self.lst_actions.Deselect(self.lst_actions.GetSelection())
        pass

    def test_action(self, e=None):
        act, str = self.cvt_control_to_action()
        if act is None:
            wx.MessageBox("当前指令无效！", "测试")
            return False
        th = CustomScriptThread(self.adb, [act], 1)
        th.run()
        pass

    def input_action_from_screen(self, e=None):
        act_sel = self.cmb_act.GetSelection()
        succ, data = self.adb.capture_screen(None, "cv2")
        if succ:
            dlg = DlgPictureWithAction(self, data)
            # old position
            if act_sel is wx.NOT_FOUND:
                pass
            elif self.act_all[act_sel] in "click|press|slide|nop":
                dlg.set_press_time(self.num_time.GetValue())
                dlg.set_points((self.num_x.GetValue(), self.num_y.GetValue()), 0)
                if self.act_all[act_sel] == "slide":
                    dlg.set_points((self.num_x2.GetValue(), self.num_y2.GetValue()), 1)
                else:
                    dlg.set_points((self.num_x.GetValue(), self.num_y.GetValue()), 1)
            dlg.ShowModal()
            # new position
            points = dlg.get_points()
            if act_sel is wx.NOT_FOUND:
                pass
            elif self.act_all[act_sel] in "click|press|slide|nop":
                tip = {"click": "请在图中模拟点击操作！", "press:": "请在图中模拟按住操作！",
                       "slide": "请在图中模拟滑动操作！", "nop": "请在按住并保持来表示等待时间！"}
                act = self.act_all[act_sel]
                if (points[1] is None) or \
                        (act in "click|press" and not points[0] == points[1]) or \
                        (act in "slide" and points[0] == points[1]) or \
                        (act in "nop" and dlg.get_press_time() <= 0):
                    wx.MessageBox(tip[act])
                else:
                    self.num_x.SetValue(points[0][0])
                    self.num_y.SetValue(points[0][1])
                    self.num_x2.SetValue(points[1][0])
                    self.num_y2.SetValue(points[1][1])
                    self.num_time.SetValue(dlg.get_press_time())
            else:
                pass
            dlg.Destroy()
        else:
            wx.MessageBox("截屏失败！" + str(data), "截屏", style=wx.ICON_ERROR)
        pass

    def record_actions(self, e=None):
        dlg = DlgActionsSimulator(self, self.adb)
        dlg.ShowModal()
        actions = dlg.actions
        act_arr = []
        self.lst_actions.ScrollLines(self.lst_actions.GetCount())
        for act in actions:
            act_data, act_str = self.cvt_points_to_action(act)
            if act_str is None:
                continue
            self.lst_actions.Append(act_str, act_data)
            self.lst_actions.ScrollLines(self.lst_actions.GetCount())

    def on_save(self, e):
        if self.txt_name.IsEmpty():
            wx.MessageBox("脚本名称不能为空", "添加脚本", parent=self)
            self.txt_name.SetFocus()
            return False
        if self.txt_file.IsEmpty():
            wx.MessageBox("脚本文件不能为空", "添加脚本", parent=self)
            self.txt_file.SetFocus()
            return False
        self.script["name"] = self.txt_name.GetValue()
        self.script_file = self.txt_file.GetValue()
        if len(self.txt_tip.GetValue().strip()) > 0:
            self.script["tip"] = self.txt_tip.GetValue()
        self.script["times"] = self.num_times.GetValue()
        num = self.lst_actions.GetCount()
        actions = []
        for i in range(num):
            d = self.lst_actions.GetClientData(i)
            actions.append(dict(d))
        self.script["actions"] = actions
        self.save_data()
        return True

    def on_ok(self, e):
        if self.on_save(e):
            self.EndModal(wx.ID_OK)

    def on_cancel(self, e):
        self.script["name"] = "None"
        self.script["file"] = "None"
        self.EndModal(wx.ID_CANCEL)
